﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AAA.Meta.Chart.Data;
using AAA.Meta.Chart.Util;
using AAA.DesignPattern.Observer;

namespace AAA.Chart.Component
{
    public partial class ProfileMChart : ProfileChartBase, IObserver 
    {
        private Dictionary<float, Dictionary<float, ProfileCharData>> _dicCellData1 = new Dictionary<float, Dictionary<float, ProfileCharData>>();
        private float fXStartIndex = 0;
        private float fXEndIndex = 0;
        private float fAxisYBoxWidth = 0;
        private float _fLastPrice;
        private List<DateTime> SelectProfileIndex = new List<DateTime>();
        private int _intSelectMode = 0; // 0 normal, 1 split, 2 merge
        private Dictionary<DateTime, int> _dicXAxis = new Dictionary<DateTime, int>();
        private Dictionary<int, List<int>> _dicVA = new Dictionary<int, List<int>>();
        private Point Mouse_Pos = new Point();

        public ProfileMChart()
        {
            InitializeComponent();
            BackColor = Color.White;
            MessageSubject.Instance().Subject.Attach(this);
        }

        public int SelectMode
        {
            get { return _intSelectMode; }
            set { _intSelectMode = value; }
        }

        public float AxisXAreaHeight
        {
            get
            {
                Graphics g = CreateGraphics();
                fAxisXAreaHeight = (g.MeasureString("0\n0\n0", _ChartFont).Height) * fScale;
                g.Dispose();
                return fAxisXAreaHeight;
            }
        }

        public float AxisYBoxWidth
        {
            get
            {
                Graphics g = CreateGraphics();
                fAxisYBoxWidth = (g.MeasureString("000,000.00", _ChartFont).Width) * fScale;
                g.Dispose();
                return fAxisYBoxWidth;
            }
        }

        public float SetScale
        {
            get { return fScale; }
            set { fScale = value; }
        }

        public float XStartIndex
        {
            get { return fXStartIndex; }
            set { fXStartIndex = value; }
        }

        public float XEndIndex
        {
            get { return fXEndIndex; }
            set { fXEndIndex = value; }
        }

        public override void AddProfileMgr(ProfileMgr pmProfileMgr)
        {
            try
            {
                float _fPriceInterval = pmProfileMgr.PriceInterval;
                float fHighest;
                float fLowest;
                int iCharCount;
                int iColBaseIndex;
                int iRowIndex;
                List<ProfileCharData> lstChar1;
                List<float> lstPrice;
                string strOpenPrice;
                _lstCellPrice.Clear();
                _dicCellData1.Clear();
                _dicXAxis.Clear();
                _dicVA.Clear();

                // Calculate price range and character range
                fHighest = -float.MaxValue;
                fLowest = float.MaxValue;
                iCharCount = 0;

                fHighest = pmProfileMgr.Highest();
                fLowest = pmProfileMgr.Lowest();
                iCharCount = pmProfileMgr.POCTPOCount();

                fHighest = (float)(Math.Ceiling(fHighest / _fPriceInterval) * _fPriceInterval) + 2 * _fPriceInterval;
                fLowest = (float)(Math.Floor(fLowest / _fPriceInterval) * _fPriceInterval) - 2 * _fPriceInterval;
                _iPriceCount = (int)((fHighest - fLowest) / _fPriceInterval) + 1;
                for (float fIndex = fHighest; fIndex >= fLowest; fIndex -= _fPriceInterval)
                {
                    _dicCellData1.Add(fIndex, new Dictionary<float, ProfileCharData>());
                    _lstCellPrice.Add(fIndex);
                }
                iColBaseIndex = 0;
                List<ProfileData> _lstProfile = pmProfileMgr.GetProfileData(pmProfileMgr.StartTime, pmProfileMgr.EndTime);
                _fLastPrice = pmProfileMgr.GetLastPrice();
                Dictionary<DateTime, Dictionary<string, int>> dicVT = pmProfileMgr.GetProfileVT();
                foreach (ProfileData dayProfile in _lstProfile)
                {
                    List<float> lstVA = dayProfile.GetProfileValueArea(); 
                    lstPrice = dayProfile.PriceList;
                    for (int i = 0; i < lstPrice.Count; i++)
                    {
                        iRowIndex = (int)((fHighest - lstPrice[i]) / _fPriceInterval);
                        strOpenPrice = dayProfile.Open.ToString();
                        lstChar1 = dayProfile.TPOCharList(lstPrice[i]);
                        for (int j = 0; j < lstChar1.Count; j++)
                        {
                            ProfileCharData cellData1 = new ProfileCharData();
                            cellData1 = lstChar1[j];
                            _dicCellData1[_lstCellPrice[iRowIndex]].Add(j + iColBaseIndex, cellData1);
                        }
                        if (!_dicVA.ContainsKey(iColBaseIndex + dayProfile.POCTPOCount()))
                        {
                            _dicVA.Add(iColBaseIndex + dayProfile.POCTPOCount(), new List<int>());
                        }
                        if (lstPrice[i] == lstVA[0])
                        {
                            _dicVA[iColBaseIndex + dayProfile.POCTPOCount()].Add(iRowIndex);
                        }
                        if (lstPrice[i] == lstVA[1])  {
                            _dicVA[iColBaseIndex + dayProfile.POCTPOCount()].Add(iRowIndex);
                        }
                    }
                    _dicXAxis.Add(dayProfile.StartTime, iColBaseIndex);
                    iColBaseIndex += (dayProfile.POCTPOCount() + 2);
                }
                _ProfileMgr = pmProfileMgr;
                //PaintChart();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
        }

        public override void PaintChart()
        {
            try
            {
                Graphics g;
                Graphics eg = CreateGraphics();
                _ChartFont = AAA.Base.Util.Graphic.FontUtil.CreateFont(eg, "細明體", FontStyle.Regular,"W", (int)BoxHeight, (int)BoxWidth);
                Bitmap bitmap = new Bitmap(Width, Height);
                g = Graphics.FromImage(bitmap);
                g.Clear(BackColor);
                DrawPYAxis(g);
                eg.DrawImage(bitmap, 0, 0);
                eg.Dispose();
                DrawSelectMode(BoxColor);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
        }

        private void DrawBox(Graphics g, float X, float Y, Color DrawColor, String strChar)
        {
            try
            {
                //g.DrawRectangle(new Pen(new SolidBrush(DrawColor), 1), X, Y, fBoxWidth * fScale, fBoxHeight * fScale);
                g.DrawString(strChar, _ChartFont, new SolidBrush(DrawColor), new Point((int)X + 1, (int)Y + 1));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
        }

        private void DrawPYAxis(Graphics g)
        {
            if (_ProfileMgr == null) 
            {
                return;
            }
            if (_ProfileMgr.GetPriceList().Count == 0) {
                return;
            }
            try
            {
                //fAxisYBoxWidth = g.MeasureString("000,000.00", _ChartFont).Width * fScale;
                int Price_Length = Convert.ToInt32(Math.Ceiling((Size.Height - AxisXAreaHeight) / fBoxHeight * fScale));
                g.DrawLine(new Pen(new SolidBrush(AxisColor), 1), AxisYBoxWidth + 2, 0, AxisYBoxWidth + 2, Height - AxisXAreaHeight);
                for (int I = (int)YStartIndex; I < YEndIndex; I++)
                {
                    if ((I < _lstCellPrice.Count) & (I >= 0))
                    {
                        float[] dashValues = { 1, 1 };
                        Pen dashPen = new Pen(GridColor, 1);
                        dashPen.DashPattern = dashValues;
                        if (_lstCellPrice[I] == ProfileUtil.CalPriceLabel(_ProfileMgr.PriceInterval, _fLastPrice))
                        {
                            g.FillRectangle(new SolidBrush(HighlightColor), AxisYBoxWidth + 4, ((I - YStartIndex)+(float)0.75) * fBoxHeight * fScale, Width, fBoxHeight * (float)0.25 * fScale);
                        }
                        g.DrawLine(dashPen, AxisYBoxWidth, (I - YStartIndex + 1) * fBoxHeight * fScale, Width, (I - YStartIndex + 1) * fBoxHeight * fScale);

                        StringFormat strYAxisFormat = new StringFormat();
                        strYAxisFormat.Alignment = StringAlignment.Far;
                        g.DrawString(String.Format("{0:##,##0.00;(##,##0.00);Zero}", _lstCellPrice[I]), _ChartFont, new SolidBrush(AxisLineColor), new RectangleF(0, (I - YStartIndex) * fBoxHeight * fScale, fAxisYBoxWidth, fBoxHeight * fScale), strYAxisFormat);
                        foreach (float TKey in _dicCellData1[_lstCellPrice[I]].Keys)
                        {
                            if ((TKey >= fXStartIndex) && (TKey <= fXEndIndex))
                            {
                                if (_dicCellData1[_lstCellPrice[I]][TKey].IsOpen)
                                {
                                    DrawBox(g, ValueToPixel(TKey, I)[0], ValueToPixel(TKey, I)[1], StartPeriodBoxColor, _dicCellData1[_lstCellPrice[I]][TKey].StrChar);
                                }
                                else
                                {
                                    DrawBox(g, ValueToPixel(TKey, I)[0], ValueToPixel(TKey, I)[1], BoxColor, _dicCellData1[_lstCellPrice[I]][TKey].StrChar);
                                }
                            }
                        }
                    }
                }
                DrawValueArea(g, Color.Red);
                DrawXAxis(g);
                g.FillRectangle(new SolidBrush(BackColor), AxisYBoxWidth, Height - AxisXAreaHeight, Width, Height);
                g.DrawLine(new Pen(new SolidBrush(AxisColor), 1), AxisYBoxWidth, Height - AxisXAreaHeight, Width, Height - AxisXAreaHeight);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
        }

        private void DrawXAxis(Graphics g)
        {
            float FHeight = (g.MeasureString("0", _ChartFont).Height) * fScale;
            int intI = 0;
            Dictionary<DateTime, Dictionary<string, int>> dicVT = _ProfileMgr.GetProfileVT();
            int intProfile = 0;
            try
            {
                foreach (DateTime ProfileStart in _dicXAxis.Keys)
                {
                    if ((_dicXAxis[ProfileStart] >= fXStartIndex) && (_dicXAxis[ProfileStart] <= fXEndIndex))
                    {
                        ProfileData dayProfile = _ProfileMgr.GetProfileData(ProfileStart)[0];
                        int intLabelY = -1;
                        for (int intPrice = 0; intPrice < _lstCellPrice.Count; intPrice++)
                        {
                            if (_lstCellPrice[intPrice] == ProfileUtil.CalPriceLabel(dayProfile.PriceInterval, dayProfile.Lowest))
                            {
                                intLabelY = intPrice;
                            }
                        }
                        if (intLabelY != -1)
                        {
                            intLabelY = (int)ValueToPixel(0, intLabelY)[1] + (int)(BoxHeight * 1.5);
                        }
                        //DrawBox(g, ValueToPixel(TKey, I)[0], ValueToPixel(TKey, I)[1], StartPeriodBoxColor, _dicCellData1[_lstCellPrice[I]][TKey].StrChar);
                        g.FillRectangle(new SolidBrush(_cStackColors[intProfile % _cStackColors.Length]), (int)(fAxisYBoxWidth + 4 + (_dicXAxis[ProfileStart] - fXStartIndex) * fBoxWidth * fScale), intLabelY, (int)(g.MeasureString(ProfileStart.ToString("yyMMdd HH:mm"), _ChartFont).Width) * fScale, fBoxHeight * 3 * fScale);
                        g.DrawString(ProfileStart.ToString("yyMMdd HH:mm"), _ChartFont, new SolidBrush(AxisColor), new Point((int)(fAxisYBoxWidth + 4 + (_dicXAxis[ProfileStart] - fXStartIndex) * fBoxWidth * fScale), intLabelY));
                        g.DrawString("V:" + dicVT[ProfileStart]["Volume"].ToString(), _ChartFont, new SolidBrush(AxisColor), new Point((int)(fAxisYBoxWidth + 4 + (_dicXAxis[ProfileStart] - fXStartIndex) * fBoxWidth * fScale), intLabelY + (int)FHeight));
                        g.DrawString("T:" + dicVT[ProfileStart]["Ticks"].ToString(), _ChartFont, new SolidBrush(AxisColor), new Point((int)(fAxisYBoxWidth + 4 + (_dicXAxis[ProfileStart] - fXStartIndex) * fBoxWidth * fScale), intLabelY + 2 * (int)FHeight));
                        intI = intI + 1;
                    }
                    intProfile++;
                }
            }
            catch ( Exception ex) {
                Console.WriteLine(ex.Message.ToString());
            }
        }

        private void DrawValueArea(Graphics g, Color VAColor) {
            foreach (int intVA_X in _dicVA.Keys)
            {
                g.DrawLine(new Pen(new SolidBrush(VAColor), 1), ValueToPixel(intVA_X, 0)[0], ValueToPixel(0, _dicVA[intVA_X][0])[1], ValueToPixel(intVA_X, 0)[0], ValueToPixel(0, _dicVA[intVA_X][1])[1]);
            }
        }

        private void DrawColorLegend(Color DrawColor)
        {
            try
            {
                Dictionary<DateTime, Color> dicLegend = new Dictionary<DateTime, Color>();
                Graphics g;
                Graphics eg = CreateGraphics();
                Bitmap bitmap = new Bitmap((int)AxisYBoxWidth, (int)AxisXAreaHeight - 4);
                g = Graphics.FromImage(bitmap);
                g.Clear(BackColor);
                g.FillRectangle(new SolidBrush(BackColor), AxisYBoxWidth, Height - AxisXAreaHeight, Width, Height);
               // g.DrawString(SelectModes[SelectMode], _ChartFont, new SolidBrush(DrawColor), new Point(2, 2));
                eg.DrawImage(bitmap, 2, Height - AxisXAreaHeight + 4);
                eg.Dispose();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }
        }

        public int[] ValueToPixel(double dX, double dY)
        {
            int[] iReturn = new int[2];
            try
            {
                iReturn[0] = (int)(fAxisYBoxWidth + 4 + (dX - fXStartIndex) * fBoxWidth * fScale);
                iReturn[1] = (int)((dY - fYStartIndex) * fBoxHeight * fScale);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
            return iReturn;
        }

        public int[] PixelToValue(double dX, double dY)
        {
            int[] iReturn = new int[2];
            try
            {
                if (dX - fAxisYBoxWidth - 4 >= 0)
                {
                    iReturn[0] = (int)Math.Floor((dX - fAxisYBoxWidth - 4) / (fBoxWidth * fScale)) + (int)fXStartIndex;
                }
                else
                {
                    iReturn[0] = -1;
                }
                iReturn[1] = (int)Math.Floor(dY / fBoxHeight * fScale) + (int)fYStartIndex;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }
            return iReturn;
        }

        private void ProfileMChart_MouseClick(object sender, MouseEventArgs e)
        {
            ProfileMChart_MouseClickAction(e, e.X, e.Y);
        }


        private void ProfileMChart_MouseClickAction(MouseEventArgs e, int X, int Y)
        {
            try
            {
                if (e.Button == MouseButtons.Right)
                {
                    ResetMenu();
                    cmMenu1.Show(this, new Point(X, Y));
                }
                else
                {
                    MoveAndShowCross();
                    float fSelectIndex = PixelToValue(float.Parse(X.ToString()), float.Parse(Y.ToString()))[0];
                    float fSelectPrice = _lstCellPrice[PixelToValue(float.Parse(X.ToString()), float.Parse(Y.ToString()))[1]];
                    if (_dicCellData1[fSelectPrice].ContainsKey(fSelectIndex))
                    {
                        ProfileCharData Chardata = _dicCellData1[fSelectPrice][fSelectIndex];
                        List<DateTime> NewListDT = new List<DateTime>();
                        NewListDT.Add(Chardata.ProfileKey);
                        NewListDT.Add(Chardata.PeriodKey);
                        switch (SelectMode)
                        {
                            case 1:
                                _ProfileMgr.Split(_ProfileMgr.GetProfileData(Chardata.ProfileKey)[0], Chardata.PeriodKey);
                                AddProfileMgr(_ProfileMgr);
                                ProfileMgrChanged();
                                SelectMode = 0;
                                break;
                            case 2:
                                if (SelectProfileIndex.Count == 2)
                                {
                                    _ProfileMgr.Merge(_ProfileMgr.GetProfileData(SelectProfileIndex[0])[0], SelectProfileIndex[1], _ProfileMgr.GetProfileData(Chardata.ProfileKey)[0], Chardata.PeriodKey);
                                    AddProfileMgr(_ProfileMgr);
                                    ProfileMgrChanged();
                                    SelectProfileIndex.Clear();
                                    SelectMode = 0;
                                }
                                else
                                {
                                    SelectProfileIndex.Add(Chardata.ProfileKey);
                                    SelectProfileIndex.Add(Chardata.PeriodKey);
                                }
                                break;
                            case 3:
                                SelectProfileIndex.Add(Chardata.ProfileKey);
                                SelectProfileIndex.Add(Chardata.PeriodKey);
                                if (SelectProfileIndex.Count == 4)
                                {
                                    SelectVolumeRange();
                                    SelectProfileIndex.Clear();
                                    SelectMode = 0;
                                }
                                break;
                        }
                        DrawSelectMode(BoxColor);
                    }
                }
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message.ToString());
            }
        }

        private void tsmMerge_Click(object sender, EventArgs e)
        {
            SelectMode = 2;
            DrawSelectMode(BoxColor);
            SelectProfileIndex.Clear();
        }

        private void tsmSplit_Click(object sender, EventArgs e)
        {
            SelectMode = 1;
            DrawSelectMode(BoxColor);
        }

        private void tsmCancel_Click(object sender, EventArgs e)
        {
            SelectMode = 0;
            DrawSelectMode(BoxColor);
            SelectProfileIndex.Clear();
        }

        private void ResetMenu()
        {
            try
            {
                tsmMerge.Enabled = false;
                tsmSplit.Enabled = false;
                tsmVolume.Enabled = false;
                tsmCancel.Enabled = false;
                switch (SelectMode)
                {
                    case 0:
                        tsmMerge.Enabled = true;
                        tsmSplit.Enabled = true;
                        tsmVolume.Enabled = true;
                        break;
                    default:
                        tsmCancel.Enabled = true;
                        break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
        }

        private void DrawSelectMode(Color DrawColor)
        {
            try
            {
                string[] SelectModes = { "        ", "Split", "Merge", "Volume" };
                Graphics g;
                Graphics eg = CreateGraphics();
                Bitmap bitmap = new Bitmap((int)AxisYBoxWidth, (int)AxisXAreaHeight - 4);
                g = Graphics.FromImage(bitmap);
                g.Clear(BackColor);
                g.DrawString(SelectModes[SelectMode], _ChartFont, new SolidBrush(DrawColor), new Point(2, 2));
                eg.DrawImage(bitmap, 2, Height - AxisXAreaHeight + 4);
                eg.Dispose();
            }
            catch (Exception e) {
                Console.WriteLine(e.Message.ToString());
            }
        }

        private void tsmVolume_Click(object sender, EventArgs e)
        {
            SelectMode = 3;
            DrawSelectMode(BoxColor);
            SelectProfileIndex.Clear();
        }

        private void SelectVolumeRange()
        {
            try
            {
                IMessageInfo miMessage = new MessageInfo();
                miMessage.MessageTicks = DateTime.Now.Ticks;
                miMessage.MessageSubject = "VolumeRangeChanged";
                miMessage.Message = SelectProfileIndex;
                MessageSubject.Instance().Subject.Notify(miMessage);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "," + ex.StackTrace);
            }
        }

        public float GetLastPriceIndex() {
            float fLastIndex = 0;
            for (int I = 0; I < _lstCellPrice.Count; I++)
            {
                if (_lstCellPrice[I] == ProfileUtil.CalPriceLabel(_ProfileMgr.PriceInterval, _fLastPrice))
                {
                    fLastIndex = I;
                }
            }
            return fLastIndex;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            PaintChart();
        }

        private void ProfileMgrChanged()
        {
            try
            {
                IMessageInfo miMessage = new MessageInfo();
                miMessage.MessageTicks = DateTime.Now.Ticks;
                miMessage.MessageSubject = "ProfileMgrChanged";
                miMessage.Message = _ProfileMgr;
                MessageSubject.Instance().Subject.Notify(miMessage);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "," + ex.StackTrace);
            }
        }

        public void Chart_ZoomInOut(int intChange)
        {
            BoxHeight = BoxHeight + intChange;
            BoxWidth = BoxWidth + intChange;
            PaintChart();
        }
        
        #region IObserver Members

        public void Update(object oSource, IMessageInfo miMessage)
        {
            try
            {
                switch (miMessage.MessageSubject)
                {
                    case "VolumeRangeChanged":
                        List<DateTime> SelectProfileIndex = (List<DateTime>)miMessage.Message;
                        //AddProfileMgr(miMessage.Message);
                        break;
                    case "ProfileMgrChanged":
                        AddProfileMgr((ProfileMgr)miMessage.Message);
                        break;
                    case "ChartCrossMoved":
                        List<string> CrossPostion = (List<string>)miMessage.Message;
                        if (Name != CrossPostion[0])
                        {
                            MoveCrossLine(int.Parse(CrossPostion[1]), int.Parse(CrossPostion[2]), 0);
                        }
                        break;
                    /*case "CrossClick":
                        List<object> M_Pos = (List<object>)miMessage.Message;
                        if ((string)M_Pos[0] == Name) {
                            ProfileMChart_MouseClickAction((MouseEventArgs)M_Pos[1], Mouse_Pos.X, Mouse_Pos.Y);
                        }
                        break;*/
                    case "ChartCrossInvisible":
                        string SenderName = (string)miMessage.Message;
                        if (SenderName != Name)
                        {
                            SetCrossLineVisible(false);
                        }
                        break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "," + ex.StackTrace);
            }
        }

        #endregion

        private void ProfileMChart_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                Mouse_Pos.X = e.X;
                Mouse_Pos.Y = e.Y;
                SetCrossLineVisible(false);
                /*MoveCrossLine(e.X, e.Y, 1);
                IMessageInfo miMessage = new MessageInfo();
                miMessage.MessageTicks = DateTime.Now.Ticks;
                miMessage.MessageSubject = "ChartCrossMoved";
                List<string> CrossPostion = new List<string>();
                CrossPostion.Add(Name);
                CrossPostion.Add(e.X.ToString());
                CrossPostion.Add(e.Y.ToString());
                miMessage.Message = CrossPostion;
                MessageSubject.Instance().Subject.Notify(miMessage);*/
                IMessageInfo miMessage = new MessageInfo();
                miMessage.MessageTicks = DateTime.Now.Ticks;
                miMessage.MessageSubject = "ChartCrossInvisible";
                miMessage.Message = Name;
                MessageSubject.Instance().Subject.Notify(miMessage);
            }
            catch (Exception ex) {
                ex.Message.ToString();
            }
        }

        private void MoveAndShowCross()
        {
            try
            {
                MoveCrossLine(Mouse_Pos.X, Mouse_Pos.Y, 1);
                IMessageInfo miMessage = new MessageInfo();
                miMessage.MessageTicks = DateTime.Now.Ticks;
                miMessage.MessageSubject = "ChartCrossMoved";
                List<string> CrossPostion = new List<string>();
                CrossPostion.Add(Name);
                CrossPostion.Add(Mouse_Pos.X.ToString());
                CrossPostion.Add(Mouse_Pos.Y.ToString());
                miMessage.Message = CrossPostion;
                MessageSubject.Instance().Subject.Notify(miMessage);
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
            }
        }
    }
}
